declare
class Buffer
   attr m buf first last n i

   meth init(N)
      m:={NewMonitor}
      buf:={NewArray 0 N-1 null}
      n:=N i:=0 first:=0 last:=0
   end

   meth put(X)
      {@m.'lock' proc {$}
         if @i>=@n then {@m.wait} {self put(X)}
         else
            @buf.@last:=X
            last:=(@last+1) mod @n
            i:=@i+1
            {@m.notifyAll}
         end
      end}
   end

   meth get(X)
      {@m.'lock' proc {$}
         if @i==0 then {@m.wait} {self get(X)}
         else
            X=@buf.@first
            first:=(@first+1) mod @n
            i:=@i-1
            {@m.notifyAll}
         end
      end}
   end
end
